package com.cskaoyan.user.controller;

import com.alibaba.fastjson.JSON;
import com.cskaoyan.mall.commons.constant.SysRetCodeConstants;
import com.cskaoyan.mall.commons.result.ResponseData;
import com.cskaoyan.mall.commons.result.ResponseUtil;
import com.cskaoyan.mall.commons.util.CookieUtil;
import com.cskaoyan.user.constants.UserRetCode;
import com.cskaoyan.user.dto.*;
import com.cskaoyan.user.service.IKaptchaService;
import com.cskaoyan.user.service.IUserLoginService;
import com.cskaoyan.user.service.IUserRegisterService;
import com.cskaoyan.user.service.IUserService;
import com.cskaoyan.user.vo.TokenUser;
import com.cskaoyan.user.vo.UserLoginVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

/**
 * @author Bowen Deng
 * @since 2022/07/08 18:14
 */
@RestController
@RequestMapping("/user")
public class UserLoginController {

    @Autowired
    IUserService userService;

    @Autowired
    IKaptchaService iKaptchaService;

    @Autowired
    IUserRegisterService iUserRegisterService;

    @Autowired
    IUserLoginService iUserLoginService;

    /**
     * 登陆验证，用于验证该用户是否在登陆状态，如果在登陆状态，token没有过期，那么应该携带jwt字符串
     * 携带jwt字符串经过网关会被解析然后在请求头中放入"user_info"这个请求头，从该请求头中可以拿出一个
     * json字符串，里面包含着用户的一些信息,我这里两个VO其实重复了
     *
     * @param request
     * @return com.cskaoyan.mall.commons.result.ResponseData
     * @author Bowen Deng
     * @since 2022/07/11 8:57 上午
     */
    @GetMapping("/login")
    public ResponseData loginVerify(HttpServletRequest request) {

        String user_info = request.getHeader("user_info");
        TokenUser tokenUser = JSON.parseObject(user_info, TokenUser.class);
        UserLoginVO userLoginVO = new UserLoginVO();
        userLoginVO.setUid(tokenUser.getUid());
        userLoginVO.setUsername(tokenUser.getUsername());
        return new ResponseUtil().setData(userLoginVO);
    }

    /**
     * 登陆，先验证验证码，然后登陆
     *
     * @param map
     * @param request
     * @return com.cskaoyan.mall.commons.result.ResponseData
     * @author Bowen Deng
     * @since 2022/07/09 9:02 上午
     */
    @PostMapping("/login")
    public ResponseData login(@RequestBody Map<String, String> map, HttpServletRequest request, HttpServletResponse response) {
        String userName = map.get("userName");
        String userPwd = map.get("userPwd");
        String captcha = map.get("captcha");
        //验证码
        KaptchaCodeRequest kaptchaCodeRequest = new KaptchaCodeRequest();
        String uuid = CookieUtil.getCookieValue(request, "kaptcha_uuid");
        kaptchaCodeRequest.setUuid(uuid);
        kaptchaCodeRequest.setCode(captcha);
        KaptchaCodeResponse kaptchaCodeResponse = iKaptchaService.validateKaptchaCode(kaptchaCodeRequest);
        if (!SysRetCodeConstants.SUCCESS.getCode().equals(kaptchaCodeResponse.getCode())) {
            return new ResponseUtil().setErrorMsg(kaptchaCodeResponse.getMsg());
        }
        //登陆
        UserLoginRequest loginRequest = new UserLoginRequest();
        loginRequest.setUserName(userName);
        loginRequest.setPassword(userPwd);
        UserLoginResponse loginResponse = iUserLoginService.login(loginRequest);
        if (SysRetCodeConstants.SUCCESS.getCode().equals(loginResponse.getCode())) {
            //添加cookie
            Cookie cookie = CookieUtil.genCookie("access_token", loginResponse.getToken(), "/", 24 * 60 * 60);
            cookie.setHttpOnly(true);
            response.addCookie(cookie);
            return new ResponseUtil().setData(loginResponse);
        }

        return new ResponseUtil().setErrorMsg(loginResponse.getMsg());
    }

    /**
     * 注册，先验证验证码，然后注册
     *
     * @param map
     * @param request
     * @return com.cskaoyan.mall.commons.result.ResponseData
     * @author Bowen Deng
     * @since 2022/07/09 9:02 上午
     */
    @PostMapping("/register")
    public ResponseData register(@RequestBody Map<String, String> map, HttpServletRequest request) {
        String email = map.get("email");
        String userName = map.get("userName");
        String userPwd = map.get("userPwd");
        String captcha = map.get("captcha");

        //验证码
        KaptchaCodeRequest kaptchaCodeRequest = new KaptchaCodeRequest();
        String uuid = CookieUtil.getCookieValue(request, "kaptcha_uuid");
        kaptchaCodeRequest.setUuid(uuid);
        kaptchaCodeRequest.setCode(captcha);
        KaptchaCodeResponse kaptchaCodeResponse = iKaptchaService.validateKaptchaCode(kaptchaCodeRequest);
        if (!SysRetCodeConstants.SUCCESS.getCode().equals(kaptchaCodeResponse.getCode())) {
            return new ResponseUtil().setErrorMsg(kaptchaCodeResponse.getMsg());
        }
        //注册
        UserRegisterRequest registerRequest = new UserRegisterRequest();
        registerRequest.setUserName(userName);
        registerRequest.setUserPwd(userPwd);
        registerRequest.setEmail(email);
        UserRegisterResponse userRegisterResponse = iUserRegisterService.userRegister(registerRequest);
        if (SysRetCodeConstants.SUCCESS.getCode().equals(userRegisterResponse.getCode())) {
            return new ResponseUtil().setData(null);
        }
        return new ResponseUtil().setErrorMsg(userRegisterResponse.getMsg());
    }

    /**
     * 此方法用于登出用户
     * 删除浏览器cookie 直接新建覆盖即可
     *
     * @param response
     * @return com.cskaoyan.mall.commons.result.ResponseData
     * @author Can
     * @since 2022/07/08 23:18
     */
    @GetMapping("/loginOut")
    public ResponseData loginOut(HttpServletResponse response) {
        Cookie token = new Cookie("access_token", null);
        //setMaxAge=0就是清除该cookie，如果之前设置了路径得再次设置同样的路径才能生效
        token.setMaxAge(0);
        token.setPath("/");
        response.addCookie(token);
        return new ResponseUtil().setData(null);
    }

    /**
     * 此方法用于注册激活用户
     * 将用户的 uid 和 username 保存到数据库里
     *
     * @param verifyRequest
     * @return com.cskaoyan.mall.commons.result.ResponseData
     * @author Can
     * @since 2022/07/08 23:34
     */
    @GetMapping("verify")
    public ResponseData verify(UserVerifyRequest verifyRequest) {
        UserVerifyResponse verifyResponse = userService.verify(verifyRequest);
        if (UserRetCode.SUCCESS.getCode().equals(verifyResponse.getCode())) {
            return new ResponseUtil().setData(null);
        }
        return new ResponseUtil().setErrorMsg(verifyResponse.getMsg());
    }
}
